﻿namespace TuneMultiCheckBox.Utils
{
  using System;
  using System.Linq.Expressions;
  using Microsoft.Xrm.Sdk;

  public class ExtendedEntity<TEntity> where TEntity : Entity, new() 
  {
    /// <summary>
    /// Initializes a new instance of the <see cref="ExtendedEntity{TEntity}"/> class. 
    /// Initializes a new instance of the <see cref="ExtendedEntity{T}"/> class.
    /// </summary>
    /// <param name="target">
    /// The target.
    /// </param>
    /// <param name="preImage">
    /// The pre image.
    /// </param>
    public ExtendedEntity(TEntity target, TEntity preImage)
    {
      this.Target = target;
      this.PreImage = preImage;
    }

    /// <summary>
    /// Gets the change entity.
    /// </summary>
    /// <value>
    /// The change entity.
    /// </value>
    public TEntity Target { get; private set; }

    /// <summary>
    /// Gets the pre image.
    /// </summary>
    /// <value>
    /// The pre image.
    /// </value>
    public TEntity PreImage { get; private set; }

    /// <summary>
    /// Gets the id.
    /// </summary>
    /// <value>The id.</value>
    public Guid? Id
    {
      get
      {
        return this.PreImage == null ? this.Target.Id : this.PreImage.Id;
      }
    }

    /// <summary>
    /// Gets the name of the logical.
    /// </summary>
    /// <value>The name of the logical.</value>
    public string LogicalName
    {
      get
      {
        return this.PreImage == null ? this.Target.LogicalName : this.PreImage.LogicalName;
      }
    }

    /// <summary>
    /// To the entity reference.
    /// </summary>
    /// <returns>EntityReference.</returns>
    public EntityReference ToEntityReference()
    {
      return new EntityReference(this.LogicalName, this.Id ?? Guid.Empty);
    }

    /// <summary>
    /// Gets the value.
    /// </summary>
    /// <typeparam name="T">Entity Field Type</typeparam>
    /// <param name="propertyExpression">The property expression.</param>
    /// <returns>
    /// Extended Field Value
    /// </returns>
    public ExtendedValue<T> GetValue<T>(Expression<Func<T>> propertyExpression)
    {
      return this.Target.GetExtendedValue(propertyExpression, this.PreImage);
    }

    /// <summary>
    /// Gets the value.
    /// </summary>
    /// <typeparam name="T">Entity Field Type</typeparam>
    /// <param name="fieldName">Name of the field.</param>
    /// <returns>
    /// Extended Field Value
    /// </returns>
    public ExtendedValue<T> GetValue<T>(string fieldName)
    {
      return this.Target.GetExtendedValue<T>(fieldName, this.PreImage);
    }
  }
}
